package com.automannn.security.sso.server.config;

import com.automannn.boot.security.configuration.AtmSecurityProperties;
import com.automannn.boot.security.constants.AtmSecurityConstants;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerEndpointsConfiguration;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfiguration;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.provider.endpoint.FrameworkEndpointHandlerMapping;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.CollectionUtils;
import org.springframework.util.PathMatcher;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * @author chenkh
 * @time 2021/3/11 23:40
 */
@Configuration
@EnableResourceServer
public class AtmResourceServerConfiguration extends ResourceServerConfigurerAdapter implements InitializingBean {

    @Autowired(required = false)
    private AuthorizationServerEndpointsConfiguration endpoints;

    @Value("${atm.sso.resource-endpoint-list:''}")
    private Set<String> resourceEndpointList;

    @Autowired
    private AtmSecurityProperties securityProperties;

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/login").permitAll()
                .anyRequest().authenticated();
        if (endpoints != null) {
            // Assume we are in an Authorization Server
            Set<String> protectedResourceSets= new HashSet<>();
            if (!CollectionUtils.isEmpty(resourceEndpointList)){
                protectedResourceSets.addAll(resourceEndpointList);
            }
            http.requestMatcher(new AtmOAuthRequestMatcher(protectedResourceSets));
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
    }

    private static class AtmOAuthRequestMatcher implements RequestMatcher {

        private Set<String> protectedResourceSets;

        public AtmOAuthRequestMatcher(Set<String> protectedResourceSets) {
            this.protectedResourceSets = protectedResourceSets;
        }

        @Override
        public boolean matches(HttpServletRequest request) {
            String requestPath = getRequestPath(request);
            PathMatcher pathMatcher = new AntPathMatcher();
            for (String path : protectedResourceSets) {
                if (pathMatcher.match(path,requestPath)) {
                    return true;
                }
            }
            return false;
        }

        private String getRequestPath(HttpServletRequest request) {
            String url = request.getServletPath();

            if (request.getPathInfo() != null) {
                url += request.getPathInfo();
            }

            return url;
        }

    }
}
